using System.Collections;
using System.Xml.Serialization;

namespace Slaks.DocumentSerialization.Document
{
	public class Node
	{
		private long m_id;
		private string m_term;
		private long m_totalTermFrequency = 1;
		private Hashtable m_sections;

		public Node()
		{
			m_sections = new Hashtable();
		}

		[XmlElement("id")]
		public long Id
		{
			get { return m_id; }
			set { m_id = value; }
		}

		[XmlElement("term")]
		public string Term
		{
			get { return m_term; }
			set { m_term = value; }
		}

		[XmlElement("total-term-frequency")]
		public long TotalTermFrequency
		{
			get
			{
				m_totalTermFrequency = 0;
				foreach (Section section in m_sections.Values)
				{
					m_totalTermFrequency += section.TermFrequency;
				}
				
				return m_totalTermFrequency;
			}
			set { m_totalTermFrequency = value; }
		}

		[XmlArrayItem("section", typeof (Section), IsNullable = false)]
		[XmlArray]
		public ICollection Sections
		{
			get { return m_sections.Values; }
		}

		/// <summary>
		/// Get Section by its related type
		/// </summary>
		/// <param name="sectionType"></param>
		/// <returns>null if section doesn't exist</returns>
		public Section GetSectionByType(Section.SectionType sectionType)
		{
			return (Section) m_sections[sectionType];
		}

		/// <summary>
		/// Add section to the node with related section type key
		/// </summary>
		/// <param name="sectionType"></param>
		/// <param name="section"></param>
		public void AddSection(Section.SectionType sectionType, Section section)
		{
			m_sections.Add(sectionType, section);
		}

		/// <summary>
		/// Get the minimum sentence number of this node found in document
		/// </summary>
		/// <returns></returns>
		public long GetMinSentenceNumber()
		{
			long sentenceNumber = long.MaxValue;
			foreach(Section section in this.Sections)
			{
				foreach(Sentence sentence in section.Sentences)
				{
					if (sentenceNumber > sentence.Number) sentenceNumber = sentence.Number;
				}
			}
			return sentenceNumber;
		}

		/// <summary>
		/// Get the maximum sentence number of this node found in document
		/// </summary>
		/// <returns></returns>
		public long GetMaxSentenceNumber()
		{
			long sentenceNumber = long.MinValue;
			foreach(Section section in this.Sections)
			{
				foreach(Sentence sentence in section.Sentences)
				{
					if (sentenceNumber < sentence.Number) sentenceNumber = sentence.Number;
				}
			}
			return sentenceNumber;
		}

		/// <summary>
		/// Return new instance of the Node
		/// </summary>
		/// <returns></returns>
		public static Node CreateNewNode()
		{
			return new Node();
		}
	}
}